package cn.wolfcode.rbac.service.impl;

import cn.wolfcode.rbac.domain.Employee;
import cn.wolfcode.rbac.domain.LoginUser;
import cn.wolfcode.rbac.ex.BusinessException;
import cn.wolfcode.rbac.service.IEmployeeServcie;
import cn.wolfcode.rbac.service.IPermissionService;
import cn.wolfcode.rbac.service.ITokenService;
import cn.wolfcode.rbac.util.JWTUtils;
import cn.wolfcode.rbac.util.RedisKey;
import cn.wolfcode.rbac.util.VerifyCodeUtil;
import cn.wolfcode.rbac.web.vo.LoginVo;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class TokenServiceImpl  implements ITokenService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private IEmployeeServcie employeeServcie;
    @Autowired
    private IPermissionService permissionService;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public String login(LoginVo vo) {
        //1.进行参数合法性校验
        if(StringUtils.isEmpty(vo.getName()) ||
           StringUtils.isEmpty(vo.getPassword()) ||
           StringUtils.isEmpty(vo.getUuid())){
            throw new BusinessException("非法参数");
        }
        //2.校验验证码是否正确
        String code = vo.getCode();
        String codeKey = RedisKey.VERIFYCODE_KEY_PREFIX+vo.getUuid();
        String redisCode = stringRedisTemplate.opsForValue().get(codeKey);
        if(StringUtils.isEmpty(redisCode)){
            throw new BusinessException("验证码过期，请重新获取");
        }
        if(!VerifyCodeUtil.verification(code,redisCode,true)){
            throw new BusinessException("验证码输入有误");
        }
        //3.校验账号密码
        // Employee employee = employeeServcie.getByNameAndPassword(vo.getName(),vo.getPassword());
        // if(employee==null){
        //     throw new BusinessException("账号密码有误");
        // }

        //4.生成UUID,拼接key,将用户的信息存储到Redis中
        // String token = createToken(employee);
        // return token;

        LoginUser details = (LoginUser) userDetailsService.loadUserByUsername(vo.getName());
        // Employee employee = details.getEmployee();

        // 用户登陆
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                details.getUsername(),
                // details.getPassword(),
                vo.getPassword(),
                details.getAuthorities()
        );

        authenticationManager.authenticate(authenticationToken);

        // 生成jwt
        return JWTUtils.createToken("login_user_name", vo.getName());
    }

    @Override
    public void logout(String token) {
        //清除Token
        String tokenKey = RedisKey.TOKEN_PREFIX+token;
        //把用户的权限清除
        String objStr = stringRedisTemplate.opsForValue().get(tokenKey);
        Employee employee = JSON.parseObject(objStr, Employee.class);
        String permissionKey = RedisKey.USER_PERMISSION_LIST_PREFIX+employee.getId();
        stringRedisTemplate.delete(permissionKey);
        stringRedisTemplate.delete(tokenKey);
    }

    private String createToken(Employee employee) {
        String token = UUID.randomUUID().toString().replace("-","");
        String tokenKey = RedisKey.TOKEN_PREFIX+token;
        stringRedisTemplate.opsForValue().set(tokenKey, JSON.toJSONString(employee),RedisKey.TOKEN_EXPIRE, TimeUnit.SECONDS);
        //根据用户ID查询该用户的权限集合List<String>
        List<String> expressionList = permissionService.queryPermissionByEId(employee.getId());
        //将用户的权限集合存储到Redis中   userPermissionList:1
        String permissionListKey = RedisKey.USER_PERMISSION_LIST_PREFIX+employee.getId();
        stringRedisTemplate.opsForValue().set(permissionListKey,JSON.toJSONString(expressionList),RedisKey.USER_PERMISSION_LIST_EXPIRE,TimeUnit.SECONDS);
        return token;
    }
}
